package cn.eng.basic.service.impl;

import cn.eng.basic.exception.BusinessException;
import cn.eng.basic.service.IVerifyCodeService;
import cn.eng.basic.util.SmsUtils;
import cn.eng.basic.util.StrUtils;
import cn.eng.basic.util.VerifyCodeUtils;
import cn.eng.user.domain.User;
import cn.eng.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    /**
     * 图形码
     * @param key
     * @return
     */
    @Override
    public String getImageCode(String key) {
        //1.通过StrUtilts生成四位图形验证码--字符串
        String code= StrUtils.getComplexRandomString(4);
        //2.将key 和图形验证码code保存在redis ,5分钟后过期
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        //3.将图形码写到图片中并且使用base64编码 并返回base64编码的字符串
       String base64Str= VerifyCodeUtils.verifyCode(115,40,code);
        return base64Str;
    }

    /**
     * 用户注册的验证码
     * @param map
     */
    @Override
    public void getSmsCode(Map<String, String> map) {
        //前端传过来的数据
        //{phone: "333", imageCode: "3123", imageCodekey: "aeefe33c-1490-4eb1-8f75-10f4be282f37"}
        //获取map 里面的三个参数
        String phone= map.get("phone");
        String imageCode= map.get("imageCode");
        String imageCodekey= map.get("imageCodekey");
        //一. 校验 - 空值校验
        if(StringUtils.isEmpty(phone)|| StringUtils.isEmpty(imageCode)){
           throw  new BusinessException("信息不能为空");
       }
        //二.校验- 图形验证码是否过期 是否正确
        Object obj=redisTemplate.opsForValue().get(imageCodekey);//根据key去获取存储在redis里面的图形验证码
       if (obj==null){
           throw new BusinessException("图形验证码过期");
       }
       if (!imageCode.equalsIgnoreCase(obj.toString())){
           throw new BusinessException("图形验证码错误");
       }
        //三. 校验- 手机验证码是是否注册
        User user= userMapper.loadByphone(phone);
       if (user!=null){
           throw new BusinessException("该手机已注册,请直接登录.若忘记密码,请联系管理员");
       }
       //四.获取手机验证码[register:13698296250-9527:23123123123]
       Object phoneCodeObj= redisTemplate.opsForValue().get("register:"+phone);
       String code=null;
       if (phoneCodeObj==null){//如果手机验证码对象为null 说明第一次获取或者获取失败了
           code = StrUtils.getRandomString(4);//生成验证码
       }else {//没有过期 或者  后续再次获取
           //上一次的时间戳
           long lodTime = Long.parseLong(phoneCodeObj.toString().split(":")[1]);
           //获取当前系统的时间戳
           long newTime=System.currentTimeMillis();
           //判断这次的时间和上一次的时间请求是否满一分钟 前端做了获取时间禁止重复点,但是防止刷新页面 ,卡bug 违规操作
           if((newTime-lodTime)<1*60*1000){
               throw new BusinessException("请勿重复发送验证码");
           }
           code = phoneCodeObj.toString().split(":")[0];//就使用那个没过期的
       }
       //五.将手机验证码保存在redis,三分钟有效
        redisTemplate.opsForValue().set("register:"+phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
       //六.向手机发送验证码
        SmsUtils.sendSms("13698296250","验证码:"+code+"请在三分钟之内使用");
        System.out.println("验证码:"+code+"请在三分钟之内使用");
    }

    /**
     * 绑定微信,获取验证码
     * @param map
     */
    @Override
    public void binderSmsCode(Map<String, String> map) {
        String phone= map.get("phone");
        //一. 校验 - 空值校验
        if(StringUtils.isEmpty(phone)){
            throw  new BusinessException("信息不能为空");
        }
        //四.获取手机验证码[register:13698296250-9527:23123123123]
        Object phoneCodeObj= redisTemplate.opsForValue().get("binder:"+phone);
        String code=null;
        if (phoneCodeObj==null){//如果手机验证码对象为null 说明第一次获取或者获取失败了
            code = StrUtils.getRandomString(4);//生成验证码
        }else {//没有过期 或者  后续再次获取
            //上一次的时间戳
            long lodTime = Long.parseLong(phoneCodeObj.toString().split(":")[1]);
            //获取当前系统的时间戳
            long newTime=System.currentTimeMillis();
            //判断这次的时间和上一次的时间请求是否满一分钟 前端做了获取时间禁止重复点,但是防止刷新页面 ,卡bug 违规操作
            if((newTime-lodTime)<1*60*1000){
                throw new BusinessException("请勿重复发送验证码");
            }
            code = phoneCodeObj.toString().split(":")[0];//就使用那个没过期的
        }
        //五.将手机验证码保存在redis,三分钟有效
        redisTemplate.opsForValue().set("binder:"+phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //六.向手机发送验证码
        //SmsUtils.sendSms("13698296250","验证码:"+code+"请在三分钟之内使用");
        System.out.println("验证码:"+code+"请在三分钟之内使用");
    }
}
